package com.uinnova.product.eam.service.bm.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.binary.core.util.BinaryUtils;
import com.binary.jdbc.Page;
import com.google.common.collect.Lists;
import com.uinnova.product.eam.base.exception.ServerException;
import com.uinnova.product.eam.comm.model.es.EamCategory;
import com.uinnova.product.eam.config.Env;
import com.uinnova.product.eam.model.EamArtifactVo;
import com.uinnova.product.eam.model.bm.FlowModelMergeParams;
import com.uinnova.product.eam.model.dm.DataModelAttribute;
import com.uinnova.product.eam.model.dm.bean.DataModelEntityNodeVo;
import com.uinnova.product.eam.service.EamCategorySvc;
import com.uinnova.product.eam.service.ICISwitchSvc;
import com.uinnova.product.eam.service.IEamArtifactSvc;
import com.uinnova.product.eam.service.impl.IamsCIPrivateSvc;
import com.uinnova.product.eam.service.impl.IamsCIRltPrivateSvc;
import com.uinnova.product.eam.service.impl.IamsCIRltSwitchSvc;
import com.uinnova.product.eam.service.utils.DataModelDiagramUtil;
import com.uinnova.product.vmdb.comm.bean.CIState;
import com.uinnova.product.vmdb.comm.model.ci.CCcCi;
import com.uinnova.product.vmdb.comm.model.ci.CcCi;
import com.uinnova.product.vmdb.provider.ci.bean.CcCiClassInfo;
import com.uinnova.project.api.diagram.v2.client.ESDiagramApiClient;
import com.uinnova.project.base.diagram.comm.model.ESDiagram;
import com.uinnova.project.base.diagram.comm.model.ESDiagramDTO;
import com.uinnova.project.base.diagram.comm.model.ESDiagramLink;
import com.uinnova.project.base.diagram.comm.model.ESDiagramNode;
import com.uino.api.client.cmdb.IRltClassApiSvc;
import com.uino.bean.cmdb.base.ESCIInfo;
import com.uino.bean.cmdb.base.ESCIRltInfo;
import com.uino.bean.cmdb.base.LibType;
import com.uino.bean.cmdb.query.ESCISearchBean;
import com.uino.bean.cmdb.query.ESRltSearchBean;
import com.uino.bean.permission.base.SysUser;
import com.uino.util.sys.SysUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 流程建模视图发布检出前置处理器
 * @author ch
 */
@Slf4j
@Component
public class FlowModelMergePreProcessor {
    @Resource
    private ICISwitchSvc ciSwitchSvc;
    @Resource
    private IamsCIRltSwitchSvc rltSwitchSvc;
    @Resource
    private ESDiagramApiClient diagramApiClient;
    @Autowired
    private EamCategorySvc categorySvc;
    @Autowired
    private IRltClassApiSvc rltClassApiSvc;
    @Resource
    private IEamArtifactSvc artifactSvc;
    @Resource
    private IamsCIPrivateSvc ciPrivateSvc;
    @Resource
    private IamsCIRltPrivateSvc rltPrivateSvc;

    /**
     * 发布前基础信息查询
     * @param dirIds 目录id
     * @param diagramIds 视图id
     * @param parentId 父级目录id
     * @return 基础信息
     */
    public FlowModelMergeParams pushBaseQuery(List<Long> dirIds, List<String> diagramIds, Long parentId){
        FlowModelMergeParams params = new FlowModelMergeParams();
        SysUser user = SysUtil.getCurrentUserInfo();
        params.setDomainId(user.getDomainId());
        params.setOwnerCode(user.getLoginCode());
        List<ESDiagram> diagramList;
        if(BinaryUtils.isEmpty(dirIds)){
            diagramList = diagramApiClient.selectByIds(diagramIds, null, Collections.emptyList());
            if(BinaryUtils.isEmpty(diagramList)) {
                throw new ServerException("当前视图不存在或已删除!");
            }
            String ownerCode = diagramList.get(0).getOwnerCode();
            params.setOwnerCode(ownerCode);
            List<Long> newDirIds = diagramList.stream().map(ESDiagram::getDirId).filter(Objects::nonNull).collect(Collectors.toList());
            if(!BinaryUtils.isEmpty(newDirIds)){
                List<EamCategory> categoryList = queryCatalog(params, newDirIds, LibType.PRIVATE);
                params.setPrivateCategoryList(categoryList);
            }
        }else{
            params.setSingleFlag(false);
            List<EamCategory> categoryList = queryCatalog(params, dirIds, LibType.PRIVATE);
            params.setPrivateCategoryList(categoryList);
            //从目录发布，则需要同时发布下一级目录
            if(!params.getSingleFlag() && !BinaryUtils.isEmpty(params.getPrivateModelList())){
                List<Long> dirIdList = categoryList.stream().map(EamCategory::getId).collect(Collectors.toList());
                Map<Long, List<EamCategory>> dirPreGroup = params.getPrivateModelList().stream().collect(Collectors.groupingBy(EamCategory::getParentId));
                for (Long dirId : dirIdList) {
                    List<EamCategory> child = dirPreGroup.get(dirId);
                    if(BinaryUtils.isEmpty(child)){
                        continue;
                    }
                    categoryList.addAll(child);
                }
                Map<Long, EamCategory> catalogMap = categoryList.stream().collect(Collectors.toMap(EamCategory::getId, each -> each, (k1, k2) -> k2));
                categoryList = Lists.newArrayList(catalogMap.values());
            }
            params.setPrivateCategoryList(categoryList);
            diagramList = diagramApiClient.selectByDirIds(dirIds, null, params.getOwnerCode(), null);
        }
        queryDiagram(params, diagramList);
        queryCi(params, params.getPrivateCategoryList(), LibType.PRIVATE);
        queryRlt(params, params.getMergeDiagramList(), LibType.PRIVATE);
        EamCategory designCategory = categorySvc.getById(parentId, LibType.DESIGN);
        if (BinaryUtils.isEmpty(designCategory)) {
            throw new ServerException("发布位置已删除，请重新选择发布位置再次发布！");
        }
        params.setParentCategory(designCategory);
        EamCategory modelRoot = categorySvc.getModelRoot(params.getModelId(), params.getOwnerCode(), LibType.PRIVATE);
        if (BinaryUtils.isEmpty(modelRoot)) {
            throw new ServerException("模型工艺顶级目录配置异常");
        }
        params.setRootModelCategory(modelRoot);
        queryExpInfo(params);
        return params;
    }

    public void queryDiagram(FlowModelMergeParams params, List<ESDiagram> diagramList){
        if(BinaryUtils.isEmpty(diagramList)){
            return;
        }
        //查询ci及rlt
        List<Long> diagramIdList = diagramList.stream().map(ESDiagram::getId).collect(Collectors.toList());
        List<ESDiagramNode> nodeList = diagramApiClient.selectNodeByDiagramIds(diagramIdList);
        List<ESDiagramLink> linkList = diagramApiClient.selectLinkByDiagramIds(diagramIdList);
        params.setMergeDiagramList(diagramList);
        params.setMergeNodeList(nodeList);
        params.setMergeLinkList(linkList);
    }

    private List<EamCategory> queryCatalog(FlowModelMergeParams params, List<Long> dirIds, LibType libType){
        List<EamCategory> categoryList = categorySvc.getByIds(dirIds, libType);
        if(BinaryUtils.isEmpty(categoryList)){
            if(params.getSingleFlag()){
                return Collections.emptyList();
            }else{
                throw new ServerException("未查询到当前目录信息,请联系管理员!");
            }
        }
        params.setModelId(categoryList.get(0).getModelId());
        if(BinaryUtils.isEmpty(params.getModelId())){
            throw new ServerException("目录信息有误,请联系管理员!");
        }
        List<EamCategory> privateModelList = categorySvc.selectByModelId(params.getModelId(), LibType.PRIVATE, params.getOwnerCode());
        if(!BinaryUtils.isEmpty(privateModelList)){
            params.setPrivateModelList(privateModelList);
            for (EamCategory each : privateModelList) {
                params.getPrivateIdMap().put(each.getId(), each);
                params.getPrivateCodeMap().put(each.getCiCode(), each);
            }
        }
        List<EamCategory> designModelList = categorySvc.selectByModelId(params.getModelId(), LibType.DESIGN, null);
        if(!BinaryUtils.isEmpty(designModelList)){
            params.setDesignModelList(designModelList);
            for (EamCategory each : designModelList) {
                params.getDesignIdMap().put(each.getId(), each);
                params.getDesignCodeMap().put(each.getCiCode(), each);
                params.getInitDesignCategroyIds().add(each.getId());
            }
        }
        return categoryList;
    }

    private void queryCi(FlowModelMergeParams params, List<EamCategory> catalogList, LibType libType){
        List<ESDiagramNode> nodes = params.getMergeNodeList();
        if(BinaryUtils.isEmpty(nodes) && BinaryUtils.isEmpty(catalogList)){
            return;
        }
        Set<String> ciCodes = new HashSet<>();
        if(!BinaryUtils.isEmpty(nodes)){
            ciCodes.addAll(DataModelDiagramUtil.getNodeCiCode(nodes));
        }
        if(!BinaryUtils.isEmpty(catalogList)){
            Set<String> assetCode = catalogList.stream().map(EamCategory::getCiCode).collect(Collectors.toSet());
            ciCodes.addAll(assetCode);
        }
        if(BinaryUtils.isEmpty(ciCodes)){
            return;
        }
        ESCISearchBean bean = new ESCISearchBean();
        bean.setPageNum(1);
        bean.setPageSize(ciCodes.size());
        bean.setDomainId(params.getDomainId());
        bean.setCiCodes(new ArrayList<>(ciCodes));
        if(LibType.PRIVATE.equals(libType)){
            bean.setOwnerCode(params.getOwnerCode());
            bean.setStates(Lists.newArrayList(CIState.CREATE_COMPLETE, CIState.CREATE_PENDING));
        }
        Page<ESCIInfo> ciPage = ciSwitchSvc.searchESCIByBean(bean, libType);
        params.setMergeCiList(ciPage.getData());
    }

    private void queryRlt(FlowModelMergeParams params, List<ESDiagram> diagramList, LibType libType) {
        List<ESDiagramLink> links = params.getMergeLinkList();
        Set<String> rltUniqueCodes = new HashSet<>();
        if(!BinaryUtils.isEmpty(links)){
            rltUniqueCodes.addAll(DataModelDiagramUtil.getLinkRltCode(links));
        }
        // 如果是发布，则可以添加一些定制化的关系逻辑
        if(!BinaryUtils.isEmpty(params.getMergeNodeList())){
            List<Long> diagramIds = diagramList.stream().map(ESDiagram::getId).collect(Collectors.toList());
            List<ESDiagramDTO> diagramDto = diagramApiClient.queryFullDiagramByIds(diagramIds);
            rltUniqueCodes.addAll(queryRltCode(diagramDto));
        }
        if(BinaryUtils.isEmpty(rltUniqueCodes)){
            return;
        }
        List<ESCIRltInfo> rltList = rltSwitchSvc.getRltByUniqueCodes(rltUniqueCodes, params.getOwnerCode(), libType);
        params.setMergeRltList(rltList);
    }

    private void queryExpInfo(FlowModelMergeParams params) {
        List<EamCategory> privateCategoryList = params.getPrivateCategoryList();
        EamCategory parentCategory = params.getRootModelCategory();
        // 获取发布参数最大层级的dirPath进行截取
        privateCategoryList.sort(Comparator.comparing(EamCategory::getDirLvl));
        EamCategory bigLvlDir = privateCategoryList.get(0);
        if (parentCategory.getDirLvl() - bigLvlDir.getDirLvl() == 1) {
            return;
        }
        String strPath = bigLvlDir.getDirPath();
        String beforeStr = StringUtils.substringBefore(strPath, "#" + bigLvlDir.getId() + "#");
        String str = StringUtils.substringAfter(beforeStr, parentCategory.getDirPath());
        List<String> strList = Arrays.asList(str.split("#"));
        List<Long> ids = strList.stream().filter(e->!BinaryUtils.isEmpty(e)).map(Long::valueOf).collect(Collectors.toList());
        // 发布模型时 上级不存在 携带上级目录进行发布
        params.setExpDirIds(ids);
        List<EamCategory> privateExpDirList = categorySvc.getByIds(ids, LibType.PRIVATE);
        List<String> expCiCodeList = new ArrayList<>();
        for (EamCategory privateExpDir : privateExpDirList) {
            if (!BinaryUtils.isEmpty(privateExpDir.getCiCode())) {
                expCiCodeList.add(privateExpDir.getCiCode());
            }
        }
        List<ESCIInfo> privateExpCiList = new ArrayList<>();
        if (!BinaryUtils.isEmpty(expCiCodeList)) {
            CCcCi cdt = new CCcCi();
            cdt.setCiCodes(expCiCodeList.toArray(new String[0]));
            cdt.setOwnerCodeEqual(params.getOwnerCode());
            privateExpCiList = ciSwitchSvc.queryESCIInfoList(params.getDomainId(), cdt, null, false, LibType.PRIVATE);
        }
        // 上级目录相关的CiCode数据
        params.setMergeExpCiList(privateExpCiList);
    }

    public Set<String> queryRltCode(List<ESDiagramDTO> diagramDto){
        List<EamArtifactVo> artifactLit = artifactSvc.queryByType(Lists.newArrayList(6, 7, 11, 12));
        List<Long> entityArtifact = artifactLit.stream().map(EamArtifactVo::getId).collect(Collectors.toList());
        CcCiClassInfo rltClass = rltClassApiSvc.getRltClassByName(1L, Env.DM_INCLUDE);
        if(BinaryUtils.isEmpty(rltClass)){
            return new HashSet<>();
        }
        return DataModelDiagramUtil.getDataModelRlt(diagramDto, entityArtifact, rltClass.getCiClass().getId());
    }

    /**
     * 检出前基础信息查询
     * @param dirId 目录id
     * @param diagramIds 视图id（单图检出时）
     * @param libType 从架构设计检出=PRIVATE,从架构资产检出=DESIGN
     * @return 基础信息
     */
    public FlowModelMergeParams pullBaseQuery(Long dirId, List<String> diagramIds, LibType libType){
        FlowModelMergeParams params = new FlowModelMergeParams();
        SysUser user = SysUtil.getCurrentUserInfo();
        params.setDomainId(user.getDomainId());
        params.setOwnerCode(user.getLoginCode());
        List<ESDiagram> diagramList;
        if(BinaryUtils.isEmpty(dirId)){
            diagramList = diagramApiClient.selectByIds(diagramIds, null, Collections.emptyList());
            if(BinaryUtils.isEmpty(diagramList)) {
                throw new ServerException("当前视图不存在或已删除!");
            }
            dirId = diagramList.get(0).getDirId();
            if(!dirId.equals(0L)){
                List<EamCategory> categoryList = queryCatalog(params, Lists.newArrayList(dirId), libType);
                params.setMergeCategoryList(categoryList);
            }
        }else{
            params.setSingleFlag(false);
            List<EamCategory> categoryList = queryCatalog(params, Lists.newArrayList(dirId), libType);
            params.setMergeCategoryList(categoryList);
            if(BinaryUtils.isEmpty(params.getDesignModelList())){
                throw new ServerException("未匹配到资产目录!");
            }
            //从架构设计目录做检出
            List<Long> designDirIds = params.getDesignModelList().stream().map(EamCategory::getId).collect(Collectors.toList());
            diagramList = diagramApiClient.selectByDirIds(designDirIds, null, null, Lists.newArrayList(1));
        }
        params.setMergeDiagramList(diagramList);
        queryDiagram(params, diagramList);
        queryCi(params, params.getDesignModelList(), LibType.DESIGN);
        queryRlt(params, diagramList, LibType.DESIGN);
        return params;
    }

    /**
     * 架构设计与架构资产数据同步处理
     * 1.对象ciCode根据业务主键一致性同步（按资产code同步）
     * 2.关系code根据对象code变更做同步处理
     * 3.流程建模目录绑定ciCode根据对象code变更做同步处理
     * 4.视图中节点node绑定对象ciCode及link绑定关系uniqueCode做同步处理
     * @param params 参数
     */
    public void sync(FlowModelMergeParams params, LibType libType){
        List<ESCIInfo> privateCiList = params.getMergeCiList();
        if(BinaryUtils.isEmpty(privateCiList)){
            return;
        }
        if(LibType.PRIVATE.equals(libType)){
            pushSyncCiCode(params);
        }else{
            pullSyncCiCode(params);
        }
        syncRltCode(params);
        Map<String, String> syncRltCodeMap = params.getSyncRltCodeMap();
        if(!BinaryUtils.isEmpty(params.getMergeRltList()) && !BinaryUtils.isEmpty(syncRltCodeMap) && LibType.PRIVATE.equals(libType)){
            Set<String> rltUniqueCodes = new HashSet<>();
            for (ESCIRltInfo each : params.getMergeRltList()) {
                String newCode = syncRltCodeMap.get(each.getUniqueCode());
                if(BinaryUtils.isEmpty(newCode)){
                    rltUniqueCodes.add(each.getUniqueCode());
                }else{
                    rltUniqueCodes.add(newCode);
                }
            }
            List<ESCIRltInfo> rltNewList = rltSwitchSvc.getRltByUniqueCodes(rltUniqueCodes, params.getOwnerCode(), LibType.PRIVATE);
            params.setMergeRltList(rltNewList);
        }
        syncCatalog(params);
        syncDiagram(params);
    }

    /**
     * 通过业务主键校验，将私有库对象ciCode与设计库同步
     * @param params 参数
     */
    private void pushSyncCiCode(FlowModelMergeParams params) {
        List<ESCIInfo> privateCiList = params.getMergeCiList();
        Map<String, String> privateCiMap = privateCiList.stream().collect(Collectors.toMap(CcCi::getCiPrimaryKey, CcCi::getCiCode, (k1, k2) -> k2));
        List<ESCIInfo> designCiList = ciSwitchSvc.getCiByPrimaryKeys(privateCiMap.keySet(), params.getOwnerCode(), LibType.DESIGN);
        if(BinaryUtils.isEmpty(designCiList)){
            return;
        }
        Map<String, String> syncCodeMap = new HashMap<>(designCiList.size());
        for (ESCIInfo each : designCiList) {
            String privateCode = privateCiMap.get(each.getCiPrimaryKey());
            if(!BinaryUtils.isEmpty(privateCode) && !privateCode.equals(each.getCiCode())){
                syncCodeMap.put(privateCode, each.getCiCode());
            }
        }
        if(BinaryUtils.isEmpty(syncCodeMap)){
            return;
        }
        params.setSyncCodeMap(syncCodeMap);
        ciPrivateSvc.replaceCiCodeInList(privateCiList, syncCodeMap);
        //更新参数传递中的ci集合
        for (ESCIInfo each : params.getMergeCiList()) {
            String designCode = syncCodeMap.get(each.getCiCode());
            if(!BinaryUtils.isEmpty(designCode)){
                each.setCiCode(designCode);
            }
        }
    }

    /**
     * 通过业务主键校验，将私有库对象ciCode与设计库同步
     * @param params 参数
     */
    private void pullSyncCiCode(FlowModelMergeParams params) {
        List<ESCIInfo> mergeCiList = params.getMergeCiList();
        Map<String, String> designCiMap = mergeCiList.stream().collect(Collectors.toMap(CcCi::getCiPrimaryKey, CcCi::getCiCode, (k1, k2) -> k2));
        List<ESCIInfo> privateCiList = ciSwitchSvc.getCiByPrimaryKeys(designCiMap.keySet(), params.getOwnerCode(), LibType.PRIVATE);
        if(BinaryUtils.isEmpty(privateCiList)){
            return;
        }
        Map<String, String> syncCodeMap = new HashMap<>(privateCiList.size());
        for (ESCIInfo each : privateCiList) {
            String code = designCiMap.get(each.getCiPrimaryKey());
            if(!BinaryUtils.isEmpty(code) && !code.equals(each.getCiCode())){
                syncCodeMap.put(each.getCiCode(), code);
            }
        }
        if(BinaryUtils.isEmpty(syncCodeMap)){
            return;
        }
        params.setSyncCodeMap(syncCodeMap);
        ciPrivateSvc.replaceCiCodeInList(privateCiList, syncCodeMap);
    }

    /**
     * 通过对象code映射集合，将私有库关系源端及目标端对象ciCode更新与设计库同步
     * @param params 参数
     */
    private void syncRltCode(FlowModelMergeParams params) {
        List<ESCIRltInfo> privateRltList = params.getMergeRltList();
        Map<String, String> syncCodeMap = params.getSyncCodeMap();
        if(BinaryUtils.isEmpty(privateRltList) || BinaryUtils.isEmpty(syncCodeMap)){
            return;
        }
        List<ESCIRltInfo> rltList = new ArrayList<>();
        ESRltSearchBean sourceBean = new ESRltSearchBean();
        sourceBean.setPageNum(1);
        sourceBean.setPageSize(10000);
        sourceBean.setDomainId(params.getDomainId());
        sourceBean.setOwnerCode(params.getOwnerCode());
        sourceBean.setSourceCiCodes(params.getSyncCodeMap().keySet());
        Page<ESCIRltInfo> sourceRltPage = rltSwitchSvc.searchRlt(sourceBean, LibType.PRIVATE);
        if(!BinaryUtils.isEmpty(sourceRltPage.getData())){
            rltList.addAll(sourceRltPage.getData());
        }
        ESRltSearchBean targetBean = new ESRltSearchBean();
        targetBean.setPageNum(1);
        targetBean.setPageSize(10000);
        targetBean.setDomainId(params.getDomainId());
        targetBean.setOwnerCode(params.getOwnerCode());
        sourceBean.setTargetCiCodes(params.getSyncCodeMap().keySet());
        Page<ESCIRltInfo> targetRltPage = rltSwitchSvc.searchRlt(sourceBean, LibType.PRIVATE);
        if(!BinaryUtils.isEmpty(targetRltPage.getData())){
            rltList.addAll(targetRltPage.getData());
        }
        Map<String, ESCIRltInfo> resultMap = rltList.stream().collect(Collectors.toMap(ESCIRltInfo::getUniqueCode, each -> each, (k1, k2) -> k2));
        rltList = Lists.newArrayList(resultMap.values());
        Map<String,String> syncRltCodeMap = rltPrivateSvc.replaceCiCodeInCiRltList(rltList, params.getSyncCodeMap());
        params.setSyncRltCodeMap(syncRltCodeMap);
    }

    private void syncCatalog(FlowModelMergeParams params){
        List<EamCategory> categoryList = categorySvc.selectByModelId(null, LibType.PRIVATE, params.getOwnerCode());
        Map<String, String> syncCodeMap = params.getSyncCodeMap();
        if(BinaryUtils.isEmpty(categoryList) || BinaryUtils.isEmpty(syncCodeMap)){
            return;
        }
        List<EamCategory> saveList = new ArrayList<>();
        for (EamCategory each : categoryList) {
            String designCode = syncCodeMap.get(each.getCiCode());
            if(BinaryUtils.isEmpty(designCode) || designCode.equals(each.getCiCode())){
                continue;
            }
            each.setCiCode(designCode);
            saveList.add(each);
        }
        if(BinaryUtils.isEmpty(saveList)){
            return;
        }
        categorySvc.saveOrUpdateList(saveList, LibType.PRIVATE);
        //将传递中的参数目录绑定ciCode做更新
        for (EamCategory each : params.getPrivateModelList()) {
            String designCode = syncCodeMap.get(each.getCiCode());
            if(BinaryUtils.isEmpty(designCode) || designCode.equals(each.getCiCode())){
                continue;
            }
            each.setCiCode(designCode);
        }
        for (EamCategory each : params.getMergeCategoryList()) {
            String designCode = syncCodeMap.get(each.getCiCode());
            if(BinaryUtils.isEmpty(designCode) || designCode.equals(each.getCiCode())){
                continue;
            }
            each.setCiCode(designCode);
        }
    }

    private void syncDiagram(FlowModelMergeParams params){
        Map<String, String> syncCodeMap = params.getSyncCodeMap();
        if(BinaryUtils.isEmpty(syncCodeMap)){
            return;
        }
        List<ESDiagramNode> nodes = diagramApiClient.selectNodeByCiCodes(Lists.newArrayList(syncCodeMap.keySet()), params.getOwnerCode());
        if(BinaryUtils.isEmpty(nodes)){
            return;
        }
        List<ESDiagramNode> replaceNodes = new ArrayList<>(nodes.size());
        for (ESDiagramNode node : nodes) {
            if(BinaryUtils.isEmpty(node.getCiCode())){
                continue;
            }
            String newCiCode = syncCodeMap.get(node.getCiCode());
            if(BinaryUtils.isEmpty(newCiCode)){
                continue;
            }
            node.setCiCode(newCiCode);
            if(!BinaryUtils.isEmpty(node.getNodeJson())){
                JSONObject nodeJson = JSONObject.parseObject(node.getNodeJson());
                nodeJson.put("ciCode", newCiCode);
                //添加处理ER图实体属性情况
                if(!BinaryUtils.isEmpty(nodeJson.get("items")) && !BinaryUtils.isEmpty(nodeJson.get("erType"))){
                    List<DataModelEntityNodeVo> items = JSONObject.parseArray(JSON.toJSONString(nodeJson.get("items")), DataModelEntityNodeVo.class);
                    for (DataModelEntityNodeVo item : items) {
                        if(BinaryUtils.isEmpty(item.getCiCode()) || BinaryUtils.isEmpty(syncCodeMap.get(item.getCiCode()))){
                            continue;
                        }
                        item.setCiCode(syncCodeMap.get(item.getCiCode()));
                        item.getAttrs().put(DataModelAttribute.ENTITY, newCiCode);
                    }
                    nodeJson.put("items", items);
                }
                node.setNodeJson(JSON.toJSONString(nodeJson));
            }
            replaceNodes.add(node);
        }
        if (!BinaryUtils.isEmpty(replaceNodes)) {
            diagramApiClient.saveNodeList(replaceNodes);
        }
        Map<String, String> syncRltCodeMap = params.getSyncRltCodeMap();
        if(BinaryUtils.isEmpty(syncRltCodeMap)){
            return;
        }
        List<ESDiagramLink> links = diagramApiClient.selectLinkByRltCodes(Lists.newArrayList(syncRltCodeMap.keySet()), params.getOwnerCode());
        if(BinaryUtils.isEmpty(links)){
            return;
        }
        List<ESDiagramLink> replaceLinkList = new ArrayList<>(links.size());
        for (ESDiagramLink link : links) {
            if(BinaryUtils.isEmpty(link.getUniqueCode()) || !syncRltCodeMap.containsKey(link.getUniqueCode())){
                continue;
            }
            link.setUniqueCode(syncRltCodeMap.get(link.getUniqueCode()));
            JSONObject linkJson = JSON.parseObject(link.getLinkJson());
            linkJson.put("rltCode", link.getUniqueCode());
            link.setLinkJson(linkJson.toString());
            replaceLinkList.add(link);
        }
        if(!BinaryUtils.isEmpty(replaceLinkList)){
            diagramApiClient.saveLinkList(replaceLinkList);
        }
    }
}
